package com.jzg.cabinet;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.LOG;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * This class echoes a string called from JavaScript.
 */
public class CabinetPlugin extends CordovaPlugin {
    public final static String TAG = "CabinetPlugin";
    public final static String SERIAL_ADDRESS = "/dev/ttyS0";
    private byte locker_type = new Byte("1");

    private CallbackContext callbackContext = null;
    private int mLastCommandId = 0;
    //dev模式箱子状态
    private boolean isOpen = false;
    private AlertDialog alertDialog = null;
    private Byte boardId;
    private Byte portId;
    private String action = null;
    private Long lazyTime = null;

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        reg();
        this.callbackContext = callbackContext;
        if (action.equals("coolMethod")) {
            String message = args.getString(0);
            this.coolMethod(message, callbackContext);
            return true;
        }
        if (action.equals("sendOpenBoxCommand")) {
            Byte board_id = new Byte(args.getString(0));
            Byte port_id = new Byte(args.getString(1));
            locker_type = new Byte(args.getString(2));
            String isDev = args.getString(3);
            this.action = "sendOpenBoxCommand";
            this.sendOpenBoxCommand(board_id, port_id, locker_type, isDev, callbackContext);
            return true;
        }
        if (action.equals("sendQueryCommand")) {
            Byte board_id = new Byte(args.getString(0));
            Byte port_id = new Byte(args.getString(1));
            locker_type = new Byte(args.getString(2));
            String isDev = args.getString(3);
            this.action = "sendQueryCommand";
            this.sendQueryCommand(board_id, port_id, locker_type, isDev, callbackContext);
            return true;
        }
        //返回boxMac
        if (action.equals("sendQueryCommand2")) {
            Byte board_id = new Byte(args.getString(0));
            Byte port_id = new Byte(args.getString(1));
            locker_type = new Byte(args.getString(2));
            this.boardId = board_id;
            this.portId = port_id;
            this.action = "sendQueryCommand2";
            String isDev = args.getString(3);
            this.sendQueryCommand(board_id, port_id, locker_type, isDev, callbackContext);
            return true;
        }

        return false;
    }

    private void coolMethod(String message, CallbackContext callbackContext) {
        if (message != null && message.length() > 0) {
            Toast.makeText(cordova.getActivity(), message, Toast.LENGTH_SHORT).show();
            callbackContext.success(message);
        } else {
            callbackContext.error("Expected one non-empty string argument.");
        }
    }

    BroadcastReceiver serialBroadCastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String s = intent.getAction();
            if (s.equals("com.cat.driver.INTENT_CAT_DRIVER_RESPONSE")) {
                doCommandResponse(intent);
                return;
            } else if (s.equals("com.cat.driver.INTENT_CAT_DRIVER_ERROR")) {
                doHandleError(intent);
            }
        }
    };


    private void sendOpenBoxCommand(Byte board_id, Byte port_id, Byte locker_type, String isDev, CallbackContext callbackContext) {
        Log.d(TAG, "sendOpenBoxCommand called");
        if ("Y".equals(isDev)) {
            isOpen = true;
            callbackContext.success();
            return;
        }
        Intent i = new Intent();
        i.setPackage("com.cat.driver.lockerdriver");
        i.setAction("com.cat.driver.INTENT_CAT_DRIVER_COMMAND");
        i.putExtra("command_id", mLastCommandId++);  //命令序列号，可以随意设置，每次唯一即可
        i.putExtra("serial_address", SERIAL_ADDRESS);  //串口地址
        i.putExtra("serial_baudrate", 9600); //串口码率
        i.putExtra("device_type", "LOCKER_BOARD_JT");  //设备类型，LOCKER_BOARD_JT 是骏通控制版
        i.putExtra("board_id", board_id);  //板卡地址
        i.putExtra("port_id", port_id);   //需要开门的端口地址
        i.putExtra("command_name", "OPEN"); //开门指令
        //0是传统锁，1是反向锁, 注意，我们假设一个柜子只会用一种锁，所以不支持一会设置0，一会设置1的情况
        i.putExtra("locker_type", locker_type);
        Toast.makeText(cordova.getActivity(), "开锁", Toast.LENGTH_SHORT).show();
        cordova.getActivity().startService(i);
    }

    void sendQueryCommand(Byte board_id, Byte port_id, Byte locker_type, String isDev, CallbackContext callbackContext) {
        Log.d(TAG, "sendQueryCommand called");
        if ("Y".equals(isDev)) {
            isOpen = true;
            showDialog(callbackContext);
            return;
        }
        Intent i = new Intent();
        i.setPackage("com.cat.driver.lockerdriver");
        i.setAction("com.cat.driver.INTENT_CAT_DRIVER_COMMAND");
        i.putExtra("command_id", mLastCommandId++);  //命令序列号，可以随意设置，每次唯一即可
        i.putExtra("serial_address", SERIAL_ADDRESS);  //串口地址
        i.putExtra("serial_baudrate", 9600); //串口码率
        i.putExtra("device_type", "LOCKER_BOARD_JT");  //设备类型，LOCKER_BOARD_JT 是骏通控制版
        i.putExtra("board_id", board_id);  //板卡地址
        i.putExtra("port_id", port_id);   //端口地址
        i.putExtra("command_name", "QUERY"); //查询

        //0是传统锁，1是反向锁, 注意，我们假设一个柜子只会用一种锁，所以不支持一会设置0，一会设置1的情况
        i.putExtra("locker_type", locker_type);
        cordova.getActivity().startService(i);
    }


    void doCommandResponse(Intent intent) {
        if (!"com.cat.driver.INTENT_CAT_DRIVER_RESPONSE".equals(intent.getAction())) {
            Log.e(TAG, "Wrong Action " + intent.getAction());
            return;
        }

        String command = intent.getStringExtra("command_name");
        boolean cmd_success = intent.getBooleanExtra("cmd_success", false);
        String result_message = intent.getStringExtra("result_message");

        Log.d(TAG, "cmd_success=" + cmd_success);
        Log.d(TAG, "result_messag=" + result_message);

        if (command.equals("OPEN")) {//TODO, Check the result here
            if (cmd_success) {
                callbackContext.success(String.valueOf(cmd_success));
                return;
            }
        } else if (command.equals("QUERY")) {
            if (cmd_success) {
                boolean have_item = intent.getBooleanExtra("have_item", false);
                boolean is_open = intent.getBooleanExtra("is_open", false);

                Log.d(TAG, "have_item=" + have_item); //只对有红外条的硬件设计
                Log.d(TAG, "is_open=" + is_open);
                Log.d(TAG, "this.action)=" + this.action);
                if ("sendQueryCommand".equals(this.action)) {
                    callbackContext.success(String.valueOf(is_open));
                } else {
                    JSONObject obj = new JSONObject();
                    try {
                        obj.put("isOpen", is_open);
                        obj.put("boardId", this.boardId);
                        obj.put("portId", this.portId);
                        callbackContext.success(obj);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                return;
            }
        }
        callbackContext.error("开锁失败");
    }

    void doHandleError(Intent intent) {
        Log.e(TAG, intent.getStringExtra("error_message"));
        callbackContext.error(intent.getStringExtra("error_message"));
    }

    private void reg() {
        //实例化过滤器；
        IntentFilter intentFilter = new IntentFilter();
        //添加过滤的Action值；
        intentFilter.addAction("com.cat.driver.INTENT_CAT_DRIVER_RESPONSE");
        intentFilter.addAction("com.cat.driver.INTENT_CAT_DRIVER_ERROR");
        cordova.getActivity().registerReceiver(serialBroadCastReceiver, intentFilter);
    }

    private synchronized void showDialog(CallbackContext callbackContext) {
        if (this.alertDialog != null && this.alertDialog.isShowing())
            return;
        long now = new Date().getTime();
        if (lazyTime != null && now <= lazyTime)
            return;
        AlertDialog.Builder builder = new AlertDialog.Builder(cordova.getActivity());
        builder.setTitle("dev模式");
        //点击对话框以外的区域是否让对话框消失
        builder.setCancelable(false);
        builder.setNegativeButton("稍后", ((dialog, which) -> {
            lazyTime = new Date().getTime() + 1000 * 30;
            dialog.dismiss();
        }));

        builder.setPositiveButton("关闭",
                (dialog, which) -> {
                    dialog.dismiss();
                    if ("sendQueryCommand".equals(this.action)) {
                        callbackContext.success("false");
                    } else {
                        try {
                            JSONObject obj = new JSONObject();
                            obj.put("isOpen", false);
                            obj.put("boardId", this.boardId);
                            obj.put("portId", this.portId);
                            callbackContext.success(obj);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
        alertDialog = builder.create();
        alertDialog = builder.show();
        Window window = alertDialog.getWindow();
        window.setGravity(Gravity.TOP);
    }
}
